home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Cracker (Expanded Edition)
/
Game Cracker (Expanded Edition).iso
/
cracks
/
Q2HDFIX.ZIP
/
PATCH.CPP
next >
Wrap
C/C++ Source or Header
|
1997-12-16
|
6KB
|
173 lines
#include <windows.h>
#include <stdio.h>
#include <sys\stat.h>
#include <io.h>
#include <fcntl.h>
/* CHANGE
0042B1CC 68 A8 47 44 00 push 4447A8h
0042B1D1 52 push edx
0042B1D2 E8 D9 25 00 00 call 0042D7B0
0042B1D7 83 C4 08 add esp,8
0042B1DA 85 C0 test eax,eax
0042B1DC 74 15 je 0042B1F3
0042B1DE 50 push eax
0042B1DF E8 AC 20 00 00 call 0042D290
0042B1E4 83 C4 04 add esp,4
0042B1E7 8D 44 24 04 lea eax,dword ptr [esp+4]
0042B1EB 50 push eax
0042B1EC FF D6 call esi
0042B1EE 83 F8 05 cmp eax,5
0042B1F1 74 63 je 0042B256
*/
/* TO
0042B1CC 90 90 90 90 90 nop nop nop nop nop
0042B1D1 90 nop
0042B1D2 90 90 90 90 90 nop nop nop nop nop
0042B1D7 90 90 90 nop nop nop
0042B1DA 90 90 nop nop
0042B1DC 90 90 nop nop
0042B1DE 90 nop
0042B1DF 90 90 90 90 90 nop nop nop nop nop
0042B1E4 90 90 90 nop nop nop
0042B1E7 90 90 90 90 nop nop nop nop
0042B1EB 90 nop
0042B1EC 90 90 nop nop
0042B1EE 33 C0 xor eax,eax
0042B1F0 90 nop
0042B1F1 74 63 je 0042B256
*/
// Note: 0xff means any value is acceptable. Handles executable
// relocation differences between versions.
BYTE abSearch[] = {
0x68, 0xff, 0xff, 0xff, 0xff,
0x52,
0xe8, 0xff, 0xff, 0xff, 0xff,
0x83, 0xc4, 0x08,
0x85, 0xc0,
0x74, 0x15,
0x50,
0xe8, 0xff, 0xff, 0xff, 0xff,
0x83, 0xc4, 0x04,
};
const int iSearchLen = sizeof(abSearch) / sizeof(abSearch[0]);
BYTE abReplace[] = {
0x90, 0x90, 0x90, 0x90, 0x90,
0x90,
0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90,
0x90, 0x90,
0x90, 0x90,
0x90,
0x90, 0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90,
0x90,
0x90, 0x90,
0x33, 0xc0,
0x90
};
const int iReplaceLen = sizeof(abReplace) / sizeof(abReplace[0]);
const char szExecutable[] = "quake2.exe";
int
main(void)
{
printf("** NOT FOR USE WITH UNLICENCED SOFTWARE **\n\n");
printf("This program patches the Quake2(tm)(r) executable so that it\n");
printf("can be run from a hard disk without the CD present.\n\n");
printf("Run this program in the same directory as quake2.exe\n");
printf("to generate quake2.exe.patched\n\n");
struct stat fileInfo;
if (stat(szExecutable, &fileInfo) == 0)
{
const int iFileSize = fileInfo.st_size;
PBYTE pBytes = new BYTE[iFileSize];
if (pBytes)
{
int fdFile = open(szExecutable, O_RDONLY | O_BINARY);
if (fdFile != -1)
{
int iRead = read(fdFile, pBytes, iFileSize);
if (iRead == iFileSize)
{
printf("Looking for the following byte sequence:\n ");
for (int iSeq = 0; iSeq < iSearchLen; iSeq++)
{
if (iSeq && !(iSeq & 7))
printf("\n ");
if (abSearch[iSeq] == 0xff)
printf("-- ", abSearch[iSeq]);
else
printf("%02x ", abSearch[iSeq]);
}
printf("\n\n");
BOOL bFound = FALSE;
for (PBYTE pByte = pBytes;
pByte < pBytes + iFileSize - iSearchLen;
pByte++)
{
for (int iSeq = 0; iSeq < iSearchLen; iSeq++)
if (abSearch[iSeq] != 0xff &&
pByte[iSeq] != abSearch[iSeq])
goto notFound;
printf("FOUND at offset 0x%08x\n", pByte - pBytes);
if (bFound)
printf("WARNING: byte sequence found more than once.\n");
for (iSeq = 0; iSeq < iReplaceLen; iSeq++)
pByte[iSeq] = abReplace[iSeq];
bFound = TRUE;
notFound: ;
}
if (bFound)
{
char szPatched[sizeof(szExecutable) + 32];
strcpy(szPatched, szExecutable);
strcat(szPatched, ".patched");
printf("Executable patched, writing new executable to: %s\n", szPatched);
int fdFile = open(szPatched, O_WRONLY | O_BINARY | O_CREAT, S_IREAD | S_IWRITE);
if (fdFile != -1)
{
int iWritten = write(fdFile, pBytes, iFileSize);
if (iWritten != iFileSize)
printf("Can't write data to %s : %s\n", szPatched, strerror(errno));
close(fdFile);
}
else
printf("Can't create %s : %s\n", szPatched, strerror(errno));
}
else
printf("Couldn't find required byte sequence to patch it\n");
}
else
printf("Can't read %s : %s\n", szExecutable, strerror(errno));
close(fdFile);
}
else
printf("Can't open %s, %s\n", szExecutable, strerror(errno));
delete [] pBytes;
}
else
printf("Can't allocate memory to hold %s\n", szExecutable);
}
else
printf("Can't open %s : %s\n", szExecutable, strerror(errno));
return 0;
}